/*
 * Networker - clientside network control
 *
 * Copyright 2007 James W. Hofmann
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#if flash9
import flash.net.Socket;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.Lib;
import flash.system.Security;
import flash.events.Event;
import flash.events.ProgressEvent;
import haxe.Serializer;

class Networker
{
	
	static var cli : Client;
	static var style : String;
	
	static public var successfulup = false;
	static public var upstatus = 0;
	
	public static function go(newstyle : String)
	{
	
		if (!NetworkDialogue.busy)
		{	

			NetworkDialogue.start();

			if (cli==null)
			{
				cli = new Client(newstyle);
			}
			else
			{
				cli.style = newstyle;
				cli.run();
			}			
			
		}
	}	
	
	public static function failure(evt : Event)
	{
		try
		{
			untyped
			{
				NetworkDialogue.write([evt.text]);
			}
		}
		catch (c : Dynamic)
		{
			NetworkDialogue.write([evt.toString()]);
		}
		NetworkDialogue.finish();
	}
	
}

class ServerApiImpl extends haxe.remoting.AsyncProxy<ServerApi> {
}

class Client implements ClientApi {

	public var style : String;
	public var recording : String;
	var bufferstart : Int;
	var bufferend : Int;
	var s : flash.net.XMLSocket;
	var scnx : haxe.remoting.SocketConnection;
	var api : ServerApiImpl;
	static public var inst : ClientApi;
	
	public function new(style : String) {
		this.style = style;
		flash.system.Security.loadPolicyFile("http://spacecreeps.com/crossdomain.xml");
		s = new flash.net.XMLSocket();
		NetworkDialogue.write(["Connecting..."]);
		s.connect("spacecreeps.com",10074);
		scnx = haxe.remoting.SocketConnection.socketConnect(s);
		s.addEventListener(flash.events.Event.CONNECT, onConnect);
		s.addEventListener(flash.events.SecurityErrorEvent.SECURITY_ERROR,error);
		s.addEventListener(flash.events.IOErrorEvent.IO_ERROR,error);
		s.addEventListener(flash.events.IOErrorEvent.NETWORK_ERROR,error);
		api = new ServerApiImpl(scnx.api);
		inst = this;
	}
	
	function onConnect(evt : Event) {
		NetworkDialogue.write(["Connected"]);
		run();
	}

	public function run()
	{
		if (style=="Numdownload")
		{
			api.downloadnumber();		
		}
		else if (style=="Recupload")
		{
			this.recording = Recorder.serialize();
			bufferstart = 0;
			bufferend = 0;
			continuedownload();
		}
		else if (style=="Recdownload")
		{
			api.downloadgame(Main.playrecording);
		}
	
	}
	
	public function uploadgame ( recording : String, lastpart : Bool )
	{
		if (this.recording==null)
		{
			this.recording = recording;
		}
		else
		{
			this.recording += recording;
		}
		NetworkDialogue.write([this.recording.length]);
		if (lastpart)
		{
			Recorder.unserialize(this.recording);
			recording = null;
			NetworkDialogue.finish();
			StartGame.playrecording = true;
			Main.timer.addEventListener(flash.events.TimerEvent.TIMER, ComponentManager.up);			
			ComponentManager.add(StartGame);
		}
		else
		{
			api.continuedownload();
		}
	}

	public function continuedownload()
	{
		if (bufferend<this.recording.length)
		{
			bufferend+=3000;
			api.uploadgame(this.recording.substr(bufferstart,3000),false);
			bufferstart+=3000;
		}
		else
		{
			api.uploadgame(this.recording.substr(bufferstart),true);		
		}
	}
	
	public function sendnumber ( num : Int )
	{
		Title.seed = num;
		Title.challengeseed = num;
		NetworkDialogue.finish();
	}
	
	public function nosuchrecording( )
	{
		NetworkDialogue.write(["Server couldn't find recording!"]);
		NetworkDialogue.finish();
	}

	public function scoreissaved( )
	{
		Networker.successfulup = true;
		NetworkDialogue.write(["Recording successfully uploaded."]);
		NetworkDialogue.finish();
	}
	
	function error(evt : Event)
	{
		try
		{
			untyped
			{
				NetworkDialogue.write([evt.text]);
			}
		}
		catch (c : Dynamic)
		{
			NetworkDialogue.write([evt.toString()]);
		}
		NetworkDialogue.finish();
	}
	
	}

#end
